Skip to content

Add UTP-bypass local emulator instrumentation runner#43

Merged
madeye merged 1 commit into
feature/rust-tun2socksfrom
chore/local-emulator-tests-no-utp
May 11, 2026
Merged

Add UTP-bypass local emulator instrumentation runner#43
madeye merged 1 commit into
feature/rust-tun2socksfrom
chore/local-emulator-tests-no-utp

Conversation

@madeye
Copy link
Copy Markdown
Owner

@madeye madeye commented May 11, 2026

Add UTP-bypass local emulator instrumentation runner

./gradlew connectedDebugAndroidTest on AGP 8.1.2 + JDK 17 dies with

java.lang.IllegalAccessError: class com.google.protobuf.GeneratedMessageV3
  tried to access method
  com.google.protobuf.CodedInputStream.shouldDiscardUnknownFields()
  (GeneratedMessageV3 in URLClassLoader; CodedInputStream in loader 'app')

before any test runs (tests=0 in the JUnit XML, APK uninstall failures
in the UTP cleanup phase). Root cause: UTP host plugins live in their
own URLClassLoader while ddmlib lives in Gradle's "app" classloader,
and each pulls its own protobuf-java version; the JVM treats the two
copies as distinct types and the cross-classloader method dispatch
fails.

AGP 8.1.2 has no useUnifiedTestPlatform=false opt-out (Google
removed that flag in 8.x), and the obvious "upgrade AGP" path
retriggers the rust-android-gradle 0.9.6 mergeJniLibFolders
duplicate-resources bug we already had to dodge.

Bypass UTP entirely with adb shell am instrument -w -- the same
path CI's android-emulator-runner action uses, which is why CI runs
the suite green while local does not. The script:

  • Builds debug + androidTest APKs via gradle (no UTP touched).
  • Auto-picks free ports if 1080/1081/8081/8082 collide locally
    (e.g. sslocal already on 8081).
  • Boots the four fake-upstream Python proxies on the host.
  • Reinstalls both APKs on the emulator.
  • Runs the instrumentation directly via adb am instrument.
  • Parses the INSTRUMENTATION_STATUS_CODE / INSTRUMENTATION_CODE
    stream to report PASS / FAIL.
  • Tears everything down on exit.

Verified locally on AVD meow_api35 (arm64-v8a, API 35): 8/8 tests
green in 0.4 s of test time.

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

`./gradlew connectedDebugAndroidTest` on AGP 8.1.2 + JDK 17 dies with

    java.lang.IllegalAccessError: class com.google.protobuf.GeneratedMessageV3
      tried to access method
      com.google.protobuf.CodedInputStream.shouldDiscardUnknownFields()
      (GeneratedMessageV3 in URLClassLoader; CodedInputStream in loader 'app')

before any test runs (tests=0 in the JUnit XML, APK uninstall failures
in the UTP cleanup phase). Root cause: UTP host plugins live in their
own URLClassLoader while ddmlib lives in Gradle's "app" classloader,
and each pulls its own protobuf-java version; the JVM treats the two
copies as distinct types and the cross-classloader method dispatch
fails.

AGP 8.1.2 has no `useUnifiedTestPlatform=false` opt-out (Google
removed that flag in 8.x), and the obvious "upgrade AGP" path
retriggers the rust-android-gradle 0.9.6 mergeJniLibFolders
duplicate-resources bug we already had to dodge.

Bypass UTP entirely with `adb shell am instrument -w` -- the same
path CI's android-emulator-runner action uses, which is why CI runs
the suite green while local does not. The script:

  - Builds debug + androidTest APKs via gradle (no UTP touched).
  - Auto-picks free ports if 1080/1081/8081/8082 collide locally
    (e.g. sslocal already on 8081).
  - Boots the four fake-upstream Python proxies on the host.
  - Reinstalls both APKs on the emulator.
  - Runs the instrumentation directly via adb am instrument.
  - Parses the INSTRUMENTATION_STATUS_CODE / INSTRUMENTATION_CODE
    stream to report PASS / FAIL.
  - Tears everything down on exit.

Verified locally on AVD meow_api35 (arm64-v8a, API 35): 8/8 tests
green in 0.4 s of test time.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@madeye madeye merged commit 1e2ab0e into feature/rust-tun2socks May 11, 2026
4 checks passed
@madeye madeye deleted the chore/local-emulator-tests-no-utp branch May 11, 2026 12:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant